﻿using ESoft.Core.Data;
using ESoft.Core.Model;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ESoft.Core.Thread
{
    public static class CallContext
    {
        static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>();

        public static void SetData(string name, object data) =>
            state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;

        public static object GetData(string name) =>
            state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null;

        public static DataContext GetDataContext(IDbContextOption _dbContextOption)
        {
            //获取BaseDbContext的完全限定名，其实这个名字没什么特别的意义，仅仅是一个名字而已，也可以取别的名字的  
            string threadName = typeof(DataContext).FullName;

            //获取key为threadName的这个线程缓存（CallContext就是线程缓存容器类）  
            object dbObj = GetData(threadName);

            //如果key为threadName的线程缓存不存在  
            if (dbObj == null)
            {
                //创建BaseDbContext类的对象实例  
                dbObj = new DataContext(_dbContextOption);
                //将这个BaseDbContext类的对象实例保存到线程缓存当中(以键值对的形式进行保存的，我这就将key设为当前线程的完全限定名了)  
                SetData(threadName, dbObj);
                return dbObj as DataContext;
            }
            return dbObj as DataContext;
        }
    }
}
